package com.uvlab.task;

import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by allen on 6/8/2016.
 */
public class JxTaskService implements JiTaskService {

   // private static ConcurrentHashMap<String, JxTask> items = null;
    Connection coon;
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
    public JxTaskService()
    {

    }

    //connect to the postgresql
    public void init() {

        String url="jdbc:postgresql://localhost:5432/task";
        try {
            Class.forName("org.postgresql.Driver").newInstance();
            coon= DriverManager.getConnection(url, "postgres", "root");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * Retrieve a list from the persistent storage.
     * @return List of the items. or null if no item is found.
     */
    @Override
    public HashMap<String, JxTask> find()
    {
        LinkedHashMap<String,JxTask> items =new LinkedHashMap<>();;
        Statement st = null;
        try {
            st = coon.createStatement();
            ResultSet rs;
            String sql="SELECT id,uuid,description,principal,deadline,state,creattime FROM TRAN0410 ORDER BY creattime DESC";
            boolean result=st.execute(sql);
            if(result)
            {
                rs=st.getResultSet();
                JxTask task;
                while(rs.next())
                {
                    String uuid= rs.getString("uuid");
                    task=new JxTask();
                    String decsription=rs.getString("description");
                    Date deadline=formatter.parse(rs.getString("deadline"));
                    Date creattime=formatter.parse(rs.getString("creattime"));
                    task.init(uuid,decsription,deadline);
                    task.setState(rs.getInt("state"));
                    task.setPrincipal(rs.getString("principal"));
                    task.setCreattime(creattime);
                    items.put(uuid,task);
                }
            }
        } catch (SQLException | ParseException e) {
            e.printStackTrace();
        }

        return  items;
    }

    public HashMap<String, JxTask> find(HashMap<String,String> params)
    {
        LinkedHashMap<String,JxTask> items =new LinkedHashMap<>();;
        Iterator iter = params.entrySet().iterator();
        String sql="SELECT id,uuid,description,principal,deadline,state,creattime FROM TRAN0410 WHERE 1=1";
        StringBuilder sb=new StringBuilder();
        sb.append(sql);
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            String key=(String)entry.getKey();
            String val=(String)entry.getValue();
            if(val!=null){
                String tmp=String.format("AND %s=%s",key,val);
                sb.append(tmp);
            }
        }
        sql=sb.toString();
        Statement st = null;
        try {
            st = coon.createStatement();
            ResultSet rs;
            boolean result=st.execute(sql);
            if(result)
            {
                rs=st.getResultSet();
                JxTask task;
                while(rs.next())
                {
                    String uuid= rs.getString("uuid");
                    task=new JxTask();
                    String decsription=rs.getString("description");
                    Date deadline=formatter.parse(rs.getString("deadline"));
                    Date creattime=formatter.parse(rs.getString("creattime"));
                    task.setCreattime(creattime);
                    task.init(uuid,decsription,deadline);
                    task.setState(rs.getInt("state"));
                    task.setPrincipal(rs.getString("principal"));
                    items.put(uuid,task);
                }
            }
        } catch (SQLException | ParseException e) {
            e.printStackTrace();
        }

        return  items;
    }

    @Override
    public List<JxTask> find(String criterion, int pagenum, int pagestep)
    {
      return  null;
    }

    /**
     * Retrieve an existing item.
     * @param id
     * @return null if the specified item doesn't exist.
     */
    @Override
    public JxTask get(String id)
    {
        JxTask task=null;
        Statement st = null;
        try {
            st = coon.createStatement();
            ResultSet rs;
            String sql=String.format("SELECT id,uuid,description,principal,deadline,state ,creattime FROM TRAN0410 WHERE uuid='%s'",id);
            boolean result=st.execute(sql);
            if(result)
            {
                rs=st.getResultSet();

                if(rs.next())
                {
                    task=new JxTask();
                    String uuid= rs.getString("uuid");
                    task=new JxTask();
                    String decsription=rs.getString("description");
                    Date deadline=formatter.parse(rs.getString("deadline"));
                    Date creattime=formatter.parse(rs.getString("creattime"));
                    task.setCreattime(creattime);
                    task.init(uuid,decsription,deadline);
                    task.setState(rs.getInt("state"));
                    task.setPrincipal(rs.getString("principal"));
                }
            }
        } catch (SQLException | ParseException e) {
            e.printStackTrace();
        }

        return task;
    }

    /**
     * Update an existing item.
     * @param id
     * @param item Generally, only those propertyies which contains non-null values
     *             are updated into the persistence storage. However, this is not
     *             always the truth.
     * @return
     */
    @Override
    public int set(String id, JxTask item) {

        String description=item.getDescription();
        String deadline=formatter.format(item.getDeadline());
        String principal=item.getPrincipal();
        int state=item.getState();
        String sql= String.format("UPDATE TRAN0410 SET description='%s',deadline='%s',principal='%s',state=%d WHERE uuid='%s';",
                description,deadline,principal,state,id );
        try {
            Statement st = coon.createStatement();
            ResultSet rs;
            st.execute(sql,Statement.RETURN_GENERATED_KEYS);
            rs=st.getGeneratedKeys();
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        }
        return 1;
    }

    @Override
    public JxTask add(JxTask item)
    {
        String uuid=UUID.randomUUID().toString();
        item.setId(uuid);
        String description=item.getDescription();
        String deadline=formatter.format(item.getDeadline());
        String creattime=formatter.format(new Date());
        String principal=item.getPrincipal();
        String sql= String.format("INSERT INTO TRAN0410 (uuid,description,deadline,principal,creattime) VALUES ('%s','%s','%s','%s','%s');",
              uuid,description,deadline,principal,creattime );
        try {
            Statement st = coon.createStatement();
            ResultSet rs;
            st.execute(sql,Statement.RETURN_GENERATED_KEYS);
            rs=st.getGeneratedKeys();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return item;
    }

    @Override
    public String remove(String id)
    {
        String sql=String.format("UPDATE TRAN0410 SET state=9 WHERE uuid='%s'",id);
        try {
            Statement st = coon.createStatement();
            ResultSet rs;
            st.execute(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return id;
    }

}
